 /*
  *  Licensed to the Apache Software Foundation (ASF) under one
  *  or more contributor license agreements.  See the NOTICE file
  *  distributed with this work for additional information
  *  regarding copyright ownership.  The ASF licenses this file
  *  to you under the Apache License, Version 2.0 (the
  *  "License"); you may not use this file except in compliance
  *  with the License.  You may obtain a copy of the License at
  *
  *    http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing,
  *  software distributed under the License is distributed on an
  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
  *
  */
 package apiwork.mina.httpserver;
 
 import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.mina.core.buffer.IoBuffer;
 
 /**
  * A HTTP response message.
  *
  * @author The Apache MINA Project (dev@mina.apache.org)
  * @version $Rev: 581234 $, $Date: 2007-10-02 22:39:48 +0900 (?, 02 10? 2007) $
  */
 public class HttpResponseMessage {
 
	 private static final byte[] CRLF = new byte[] { 0x0D, 0x0A };
	 
     /** Map<String, String> */
     private final Map<String, String> headers = new HashMap<String, String>();
 
     /** Storage for body of HTTP response. */
     private final ByteArrayOutputStream body = new ByteArrayOutputStream(8192);
 
     private int responseCode = HttpStatus.OK;
     
     private String server = "";
 
     public HttpResponseMessage() {
         headers.put("Server", "HttpServer");
         headers.put("Cache-Control", "private");
         headers.put("Content-Type", "text/html; charset=iso-8859-1");
         headers.put("Connection", "keep-alive");
         headers.put("Keep-Alive", "200");
         headers.put("Date", new SimpleDateFormat(
                 "EEE, dd MMM yyyy HH:mm:ss zzz").format(new Date()));
         headers.put("Last-Modified", new SimpleDateFormat(
                 "EEE, dd MMM yyyy HH:mm:ss zzz").format(new Date()));
     }
 
     public Map<String, String> getHeaders() {
         return headers;
     }
 
     public void setContentType(String contentType) {
         headers.put("Content-Type", contentType);
     }
 
     public void setResponseCode(int responseCode) {
         this.responseCode = responseCode;
     }
 
     public int getResponseCode() {
         return this.responseCode;
     }
 
     public void appendBody(byte[] b) {
         try {
             body.write(b);
         } catch (IOException ex) {
             ex.printStackTrace();
         }
     }
 
     public void appendBody(String s) {
         try {
             body.write(s.getBytes());
         } catch (IOException ex) {
             ex.printStackTrace();
         }
     }
 
     public IoBuffer getBody() {
         return IoBuffer.wrap(body.toByteArray());
     }
 
     public int getBodyLength() {
         return body.size();
     }

	public String getServer() {
		return server;
	}

	public void setServer(String server) {
		this.server = server;
		headers.put("Server", server);
	}
	
	public IoBuffer encode(CharsetEncoder encoder) throws Exception {
		IoBuffer buf = IoBuffer.allocate(256);
		buf.setAutoExpand(true);

		try {
			buf.putString("HTTP/1.1 ", encoder);
			buf.putString(String.valueOf(getResponseCode()), encoder);
			switch (getResponseCode()) {
			case HttpStatus.OK:
				buf.putString(" OK", encoder);
				break;
			case HttpStatus.NotFound:
				buf.putString(" Not Found", encoder);
				break;
			}
			buf.put(CRLF);
			for (Entry<String, String> entry : getHeaders().entrySet()) {
				buf.putString(entry.getKey(), encoder);
				buf.putString(": ", encoder);
				buf.putString(entry.getValue(), encoder);
				buf.put(CRLF);
			}
			// now the content length is the body length
			buf.putString("Content-Length: ", encoder);
			buf.putString(String.valueOf(getBodyLength()), encoder);
			buf.put(CRLF);
			buf.put(CRLF);
			// add body
			buf.put(getBody());
			// System.out.println("\n+++++++");
			// for (int i=0; i<buf.position();i++)
			//	System.out.print(new String(new byte[]{buf.get(i)}));
			//  System.out.println("\n+++++++");
		} catch (CharacterCodingException ex) {
			ex.printStackTrace();
		}
		buf.flip();
		return buf;
	}
 }
